package com.neuedu.ec.controller;

import com.alibaba.fastjson.JSON;
import com.neuedu.ec.common.CommonResult;
import com.neuedu.ec.common.HttpsClientRequestFactory;
import com.neuedu.ec.common.WeChatUtils;
import com.neuedu.ec.vo.Code2Session;
import com.neuedu.ec.vo.WeChatUserInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * 用户授权
 * @author 张金山 https://jshand.gitee.io/
 */
@RequestMapping("/user")
@RestController
@Scope(value="prototype")
public class UserController {

    private Logger logger = LoggerFactory.getLogger(UserController.class);

    String baseUrl = "https://api.weixin.qq.com/sns/jscode2session";

    @Value("${wechat.appid}")
    private String appid;

    @Value("${wechat.secret}")
    private String secret;

    @Value("${wechat.grant_type}")
    private String grant_type;


    /**
     * code换Session
     * @param js_code
     * @param appid 小程序appid(因为教学原因需要传递不同的appid)
     * @param secret 小程序secret(因为教学原因需要传递不同的appid)
     * @return
     */
    @RequestMapping("/code2Session2")
    public CommonResult<Map> code2Session(String js_code,String appid,String secret) {

        Code2Session code2Session = getSessionByCode(js_code,appid,secret);
        System.out.println("code2Session:" + code2Session);

        return CommonResult.success(code2Session);
    }

    /**
     * 调用code2Session接口 私有方法
     * @param js_code
     * @param appid 小程序appid(因为教学原因需要传递不同的appid,生产上应该是在服务器配置的)
     * @param secret 小程序secret(因为教学原因需要传递不同的appid,生产上应该是在服务器配置的)
     * @return
     */
    private Code2Session getSessionByCode(String js_code, String appid, String secret) {
        if(StringUtils.isEmpty(appid)){ //如果小程序不传，则使用系统固定的
            appid = this.appid;
        }
        if(StringUtils.isEmpty(secret)){ //如果小程序不传，则使用系统固定的
            secret = this.secret;
        }
        RestTemplate restTemplate = new RestTemplate(new HttpsClientRequestFactory());
        Map<String, Object> paramMap = new HashMap<String, Object>();

        String url = baseUrl + "?appid=" + appid
                + "&secret=" + secret
                + "&grant_type=" + grant_type
                + "&js_code=" + js_code;

        String json = restTemplate.getForObject(url, String.class);

        Code2Session code2Session = JSON.parseObject(json,Code2Session.class);
        return code2Session;
    }


    /**
     *
     * 获取用户token
     * @param code  执行小程序登录后获取
     * @param encryptedData 执行小程序获取用户信息后得到,要保证跟code是同步刷新的
     * @param iv 执行小程序获取用户信息后得到
     * @param signature 执行小程序获取用户信息后得到
     * @param rawData 执行小程序获取用户信息后得到
     * @param appid 小程序appid(因为教学原因需要传递不同的appid)
     * @param secret 小程序secret(因为教学原因需要传递不同的appid)
     * @return
     */
    @RequestMapping("/wxlogin")
    public CommonResult<WeChatUserInfo> wxlogin(
                                @RequestParam("code") String code,
                                String encryptedData,
                                String iv,
                                String signature,
                                String rawData,
                                String appid,
                                String secret
                                 ) {

        logger.info("微信登录接口被访问");

        Code2Session code2Session = getSessionByCode(code,appid,secret);


        if(StringUtils.isNotEmpty(code2Session.getErrcode())){
            return CommonResult.failed("errcode:"+code2Session.getErrcode()+"   ,  msg:"+code2Session.getErrmsg());
        }

        //将密文信息解析出来
        String sessionKey = code2Session.getSession_key();
        String userInfoJson = WeChatUtils.getUserInfo(encryptedData, iv, sessionKey);

        //可以拿到userInfo 到服务器上验证 是否真实的签名
        logger.info("解密的用户信息\r\n\r\n"+userInfoJson+"\r\n\r\n\r\n");

        /**
         * 后面可以代用二次验证接口，验证用户的密钥数据是否和微信小程序服务器的签名一致
         * 参考文档：
         * https://res.wx.qq.com/wxdoc/dist/assets/img/signature.8a30a825.jpg
         * https://developers.weixin.qq.com/minigame/dev/guide/open-ability/signature.html#%E5%8A%A0%E5%AF%86%E6%95%B0%E6%8D%AE%E8%A7%A3%E5%AF%86%E7%AE%97%E6%B3%95
         *  此处暂时未做
         */

        WeChatUserInfo weChatUserInfo= JSON.parseObject(userInfoJson,WeChatUserInfo.class);

        //设置jwt-token数据
        weChatUserInfo.setToken(WeChatUtils.getUserToken(weChatUserInfo));


        return CommonResult.success(weChatUserInfo);
    }





}